package com.fisherman.config;

import com.fisherman.bean.Car;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;

/**
 * @User: fisherman
 * @Date: 2020/5/20 11:09
 *
 * bean的生命周期
 *      bean创建---初始化---销毁过程
 * 容器管理bean的生命周期
 * 我们可以自定义初始化和销毁方法，容器再bean进行到当前生命周期的时候来调用我们自定义的初始化和销毁过程
 *
 * 构造(对象创建)
 *      单实例：在容器启动的时候创建对象
 *      多实例：在每次获取的时候创建对象
 *BeanPostProcessor.postProcessBeforeInitialization在初始化之前工作
 *初始化
 *      对象创建完成，并赋值好，调用初始化方法
 *BeanPostProcessor.postProcessAfterInitialization:在初始化之后工作.
 * 销毁
 *      单实例：容器关闭的时候
 *      多实例：容器不会管理这个bean；容器不会调用销毁方法
 *
 *
 *
 *
 * 1。指定初始化和销毁方法
 *     通过@bean注解 指定的方法（xml中配置） init-method=""  destroy-method=""
 * 2.通过让Bean实现InitializingBean（定义初始化逻辑）
 *                  DisposableBean(定义销毁逻辑)
 * 3.可以使用JSR250
 *      @PostConstruct ,在bean创建完成并且属性赋值完成，来执行初始化方法
 *      @PreDestry ,在容器销毁bean之前通知我们进行清理工作
 * 4.BeanPostProcessor 【interface】,bean的后置处理器
 *          在bean初始化前后进行一些处理工作
 *          postProcessBeforeInitialization:在初始化之前工作
 *          postProcessAfterInitialization:在初始化之后工作.
 *
 *  BeanPostProcessor原理
 *  遍历得到容器中所有的BeanPostProcessor，挨个执行postProcessBeforeInitialization，
 *  一但返回null，跳出for循环，不会执行遍历得到容器中所有的BeanPostProcessor.postProcessorsBeforeInitialization
 *  populateBean(beanName, mbd, instanceWrapper);给bean进行属性赋值的
 *  initializeBean {
 *      applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
 *      invokeInitMethods(beanName, exposedObject, mbd);执行自定义初始化
 *      applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
 *  }
 *  Spring底层对BeanPostProcessor使用
 *      bean赋值，注入其他组件，@Autowired，生命周期注解功能，@Async等
 */
@ComponentScan("com/fisherman/bean")
@Configuration  //说明这是个配置类
public class MainConfigOfLifeCycle {
    @Scope("prototype")  //多实例情况下
    @Bean(initMethod = "init",destroyMethod = "detory")
    public Car car(){
        return  new Car();
    }
}
